/**
 * 树状图
 * @author zxy
 * @date  2021-01-06
 */
import React from 'react';
import PropTypes from 'prop-types';
import ReactEcharts from 'echarts-for-react';
import { Spin } from 'antd';
import { NoDataC } from '../../other';
import Color from '../../../css/colors';

class TreeChartsC extends React.Component {
  // 入参默认值设置
  static defaultProps = {
    height: '100%', // 图形高度默认为父节点的100%
    width: '100%', // 图形宽度默认为父节点的100%
    title: '',
    type: 1,
    data: undefined,
    colors: Color.echartItems, // 默认系统色
    selectedOnChange: () => {}, // 抛出节点变更事件
  };

  state = {
    latestId: undefined, // 最后一次点击的node的ID
    treeData: undefined, // 树数据源
  };

  componentDidMount() {
    this.setState({
      treeData: this.props.data,
      latestId: undefined,
    });
  }

  componentDidUpdate(prevProps, prevState, snapshot) {
    const treeDataT = prevProps.data ? JSON.stringify(prevProps.data) : '';
    const treeDataN = this.props.data ? JSON.stringify(this.props.data) : '';
    if (treeDataT != treeDataN) {
      this.setState({
        treeData: this.props.data,
        latestId: undefined,
      });
    }
  }

  // 返回option
  getOption = () => {
    const { colors } = this.props;

    return {
      // 主标题和副标题
      backgroundColor: Color.echartItems.bgColor, // echarts整个画布的背景色
      title: {
        show: false,
      },
      // 提示信息
      tooltip: {
        show: false,
      },
      // grid:{
      //   left:'30%'
      // },
      series: {
        type: 'tree',

        top: 100,
        left: 50,
        bottom: 100,
        right: 100,

        symbol:
          'image://',
        symbolSize: 15,
        edgeShape: 'polyline',
        edgeForkPosition: '63%',
        // initialTreeDepth: 3,

        lineStyle: {
          width: 0.5,
          color: colors.treeBorder,
        },

        label: {
          backgroundColor: colors.treeNumberBg,
          position: 'right',
          verticalAlign: 'middle',
          align: 'left',
          distance: 5,
          formatter: (params) => {
            return `{normal|${params.name}}`;
          },
          rich: {
            normal: {
              color: colors.treeText,
              fontSize: 14,
              backgroundColor: colors.treeTextBg,
              padding: [14, 14, 14, 14],
            },
            select: {
              color: colors.treeSelectColor,
              fontSize: 14,
              backgroundColor: colors.treeSelectBg,
              padding: [14, 14, 14, 14],
            },
          },
        },

        leaves: {
          label: {
            position: 'right',
            verticalAlign: 'middle',
            align: 'left',
          },
        },

        expandAndCollapse: false,
        animationDuration: 550,
        animationDurationUpdate: 750,
        data: this.state.treeData,
      },
    };
  };

  // 遍历找到指定节点
  find = undefined;

  findNode = (nodeId, node) => {
    node &&
      node.forEach((element) => {
        if (element.value == nodeId) {
          this.find = element;
        } else if (element.children && element.children.length > 0) {
          this.findNode(nodeId, element.children, find);
        }
      });
  };

  // 点击节点
  click = (e) => {
    // 遍历找到data中上一个选中的节点，变更该节点为非选中状态
    this.find = undefined;
    this.findNode(this.state.latestId, this.state.treeData);
    if (this.find) {
      delete this.find.label;
    }

    // 遍历找到data中的该节点，变更该节点样式为选中状态
    this.find = undefined;
    this.findNode(e.value, this.state.treeData);
    if (this.find) {
      this.find.label = {
        formatter: (params) => {
          return `{select|${params.name}}`;
        },
      };
    }

    this.setState({
      treeData: this.state.treeData,
      latestId: e.value,
    });

    this.props.selectedOnChange({ value: e.value, name: e.name });
  };

  render() {
    const { width, height } = this.props;
    const { treeData } = this.state;

    return (
      <div style={{ width }}>
        <Spin spinning={!treeData} tip='加载中...'>
          {treeData ? (
            treeData.length > 0 ? (
              <ReactEcharts
                option={this.getOption()}
                style={{ height, width }}
                // 是否不跟之前设置的 option 进行合并，默认为 false，即合并。
                notMerge={true}
                onEvents={{
                  click: this.click,
                }}
              />
            ) : (
              <NoDataC />
            )
          ) : (
            <div style={{ height, width }}></div>
          )}
        </Spin>
      </div>
    );
  }
}

/*
备注：
  当data值为null或undefined时，显示loading状态
  当data值为空数组[]时，显示“暂无数据”
  当data值为有值的数组时，正常实现图形
*/
TreeChartsC.propsTypes = {
  height: PropTypes.oneOfType([
    // 图表高度（百分比、数值、auto(自动根据图例数量计算高度)）
    PropTypes.string,
    PropTypes.number,
  ]),
  width: PropTypes.oneOfType([
    // 图表宽度（百分比或数值）
    PropTypes.string,
    PropTypes.number,
  ]),
  title: PropTypes.string,
  type: PropTypes.number, // 1-展示名字+数据（正红负绿） 2-展示名字
  data: PropTypes.array, // 树形结构数据[name:'节点名称', value:'节点ID', children:[]]
  selectedOnChange: PropTypes.func, // 抛出点击事件（value和name）
};

export default TreeChartsC;
